package kandroid.proxy

import kandroid.config.Config
import kandroid.utils.log.Logger
import org.eclipse.jetty.proxy.ConnectHandler
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.ServerConnector
import org.eclipse.jetty.servlet.ServletContextHandler
import org.eclipse.jetty.servlet.ServletHolder
import java.net.BindException
import java.util.concurrent.TimeUnit

object ProxyServer {

    var server: Server? = null

    private var host: String? = null
    private var port: Int = 0
    private var proxyHost: String? = null
    private var proxyPort: Int = 0

    fun start() {
        Thread {
            val server = Server()
            updateSetting()
            setConnector(server)

            val connectHandler = ConnectHandler()
            server.handler = connectHandler

            val servletContextHandler = ServletContextHandler(
                    connectHandler, "/", ServletContextHandler.SESSIONS)
            val holder = ServletHolder(ProxyServlet())
            holder.setInitParameter("idleTimeout", TimeUnit.MINUTES.toMillis(2).toString())
            holder.setInitParameter("timeout", TimeUnit.MINUTES.toMillis(2).toString())
            servletContextHandler.addServlet(holder, "/*")

            try {
                server.start()
                this.server = server
            } catch (e: Exception) {
                if (e is BindException) {
                }//端口被占用
                Logger.e("Proxy启动失败 -> $e", e)
            }
        }.start()
    }

    private fun setConnector(server: Server) {
        //SSL Support
        val connector = ServerConnector(server)
        connector.port = port
        connector.host = host
        server.connectors = arrayOf(connector)
    }

    private fun updateSetting(): Boolean {
        val newHost = "localhost"
        val newPort = Config.listenPort

        var newProxyHost: String? = null
        var newProxyPort = 0
        if (Config.isUseProxy) {
            newProxyHost = Config.proxyHost
            newProxyPort = Config.proxyPort
        }

        if (newHost == host && newProxyPort == proxyPort &&
                newProxyHost == proxyHost && newPort == port) {
            return false
        }

        host = newHost
        port = newPort
        proxyHost = newProxyHost
        proxyPort = newProxyPort
        return true
    }

    fun restart() {
        try {
            val server = server ?: return
            if (updateSetting()) {
                server.stop()
                setConnector(server)
                server.start()
            }
        } catch (e: Exception) {
            Logger.e("Proxy重启失败 -> $e", e)
        }
    }

    fun stop() {
        try {
            val server = server ?: return
            server.stop()
            server.join()
            this.server = null
        } catch (e: Exception) {
            Logger.e("Proxy停止失败 -> $e", e)
        }
    }
}
